package com.jumi.microservice.service.logistics.admin;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.openservices.ons.api.Message;
import com.aliyun.openservices.ons.api.bean.ProducerBean;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.jumi.microservice.common.exception.BaseException;
import com.jumi.microservice.common.redis.RedisCache;
import com.jumi.microservice.common.utils.DateUtil;
import com.jumi.microservice.config.TimeConfiguration;
import com.jumi.microservice.domain.ExpressDataDTO;
import com.jumi.microservice.domain.GoodsSkuMaterialDTO;
import com.jumi.microservice.domain.MessageTemplate;
import com.jumi.microservice.dto.excel.ExportOrderAllResponse;
import com.jumi.microservice.dto.excel.ImportNoSelfResponse;
import com.jumi.microservice.dto.logistics.NoticeMaterialRequest;
import com.jumi.microservice.dto.logistics.admin.EditOrPartSendRequest;
import com.jumi.microservice.dto.logistics.admin.UpdateRealLogisticsNoRequest;
import com.jumi.microservice.dto.logistics.excel.BatchUpdateRealLogisticsNo;
import com.jumi.microservice.dto.logistics.excel.SelfWaitSend;
import com.jumi.microservice.dto.reponse.JmUserReponse;
import com.jumi.microservice.dto.reponse.UserExternalResponse;
import com.jumi.microservice.entity.*;
import com.jumi.microservice.enumerate.LogisticsStatusEnum;
import com.jumi.microservice.enumerate.OrderStatusEnum;
import com.jumi.microservice.enumerate.SelfFlagEnum;
import com.jumi.microservice.mapper.*;
import com.jumi.microservice.rocketmq.SendMessageHandler;
import com.jumi.microservice.service.BasicDataApi;
import com.jumi.microservice.service.BasicDataService;
import com.jumi.microservice.service.IMemberService;
import com.jumi.microservice.service.IUserExternalService;
import com.jumi.microservice.warehouseout.api.ApiChangeShippingCodeService;
import com.jumi.microservice.warehouseout.vo.JmOrderWarehouseOutVo;
import com.jumi.microservice.warehouseout.vo.ShipingCodeDto;
import org.apache.dubbo.config.annotation.DubboReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author by mazhao
 * @Classname SendService
 * @Description TODO
 * @Date 2020/Integer.parseInt(timeConfiguration.getConfirmTimeMinute)/24 9:41
 */
@Service
public class SendService {

    private static final Logger log = LoggerFactory.getLogger(SendService.class);

    @Resource
    LogisticsGoodsMapper logisticsGoodsMapper;

    @Resource
    OrderGoodsMapper orderGoodsMapper;

    @Resource
    UserOrderMapper userOrderMapper;

    @Resource
    OrderLogisticsMapper orderLogisticsMapper;

    @DubboReference
    BasicDataApi iExpressService;

    @DubboReference
    BasicDataService basicDataService;

//    @DubboReference
//    ApiOrderWarehouseOutService iMaterialService;

    @DubboReference
    IMemberService iMemberService;

    @DubboReference
    ApiChangeShippingCodeService iChangeLogisticsNoService;

    @Resource
    SendMessageHandler sendMessageHandler;

    @Resource
    OrderLogMapper orderLogMapper;
    @Resource
    ProducerBean producerBean;
    @Resource
    TimeConfiguration timeConfiguration;
    @Resource
    RedisCache redisCache;
    @DubboReference
    private IUserExternalService userExternalService;
    @Resource
    AsyncSendService asyncSendService;

    /**
     * 自营待发货错误数据
     */
    public static List<String> selfWaitSendError = new ArrayList<>();
    /**
     * 非自营待发货错误数据
     */
    public static List<String> noSelfWaitSendError = new ArrayList<>();
    /**
     * 部分发货错误数据
     */
    public static List<String> partSendError = new ArrayList<>();

    /**
     * 批量修改物流单号错误数据
     */
    public static List<String> updateLogisticsNoError = new ArrayList<>();


    /**
     * 快递公司列表
     *
     * @return
     */
    public List<ExpressDataDTO> getExpressList() {
        return iExpressService.selectExpressList().stream().filter(c->c.getExpressCode()!=null && c.getStatus()==1 && c.getIsDel()==0)
                .collect(Collectors.toList());
    }

    /**
     * 编辑发货提交
     *
     * @param request
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean editSendSubmit(EditOrPartSendRequest request, Long uid, String name) {
        QueryWrapper<LogisticsGoods> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("del_flag", 0).eq("order_id", request.getOrderId())
                .eq("goods_id", request.getGoodsId())
                .in("logistics_status", LogisticsStatusEnum.WAIT_SEND.getCode(), LogisticsStatusEnum.PART_SEND.getCode());
        List<LogisticsGoods> logisticsGoodsList = logisticsGoodsMapper.selectList(queryWrapper);
        List<LogisticsGoods> warehouseOut = new ArrayList<>();
        List<Long> goodsIds = new ArrayList<>();
        if(logisticsGoodsList.isEmpty()){
            throw new BaseException(500,"未查询到待发货包裹商品");
        }
        logisticsGoodsList = logisticsGoodsList.stream().sorted(Comparator.comparing(LogisticsGoods::getLogisticsStatus).reversed().thenComparing(LogisticsGoods::getGoodsAmount)).collect(Collectors.toList());
        int realSendAmount = request.getRealSendAmount();
        boolean b = logisticsGoodsList.stream().map(LogisticsGoods::getLogisticsStatus).collect(Collectors.toList()).contains(LogisticsStatusEnum.PART_SEND.getCode());
        int index = 0;
        for (LogisticsGoods logisticsGoods : logisticsGoodsList) {
            if (realSendAmount == 0) {
                break;
            }
            index++;
            int remainSendAmount = logisticsGoods.getGoodsAmount() - logisticsGoods.getRealSendAmount();
            logisticsGoods.setRemark("");
            if (request.getRemark() != null && !request.getRemark().trim().isEmpty()) {
                logisticsGoods.setRemark(request.getRemark());
            }
            if (realSendAmount >= remainSendAmount && !b) {
                logisticsGoods.setRealSendAmount(logisticsGoods.getGoodsAmount());
                logisticsGoods.setLogisticsStatus(LogisticsStatusEnum.WAIT_RECEIVE.getCode());
                realSendAmount = realSendAmount - logisticsGoods.getGoodsAmount();
            } else if (realSendAmount < remainSendAmount && !b) {
                logisticsGoods.setRealSendAmount(realSendAmount);
                logisticsGoods.setLogisticsStatus(LogisticsStatusEnum.PART_SEND.getCode());
                realSendAmount = 0;
            }
            if (b && index == 1) {
                LogisticsGoods newLogisticsGoods = new LogisticsGoods();
                BeanUtils.copyProperties(logisticsGoods, newLogisticsGoods);
                newLogisticsGoods.setRealLogisticsNo(request.getRealLogisticsNo());
                newLogisticsGoods.setExpressCode(request.getLogisticsCompany());
                newLogisticsGoods.setRealWarehouse(request.getRealWarehouse());
                newLogisticsGoods.setId(null);
                newLogisticsGoods.setGoodsAmount(remainSendAmount);
                if (realSendAmount >= remainSendAmount) {
                    newLogisticsGoods.setRealSendAmount(remainSendAmount);
                    newLogisticsGoods.setLogisticsStatus(LogisticsStatusEnum.WAIT_RECEIVE.getCode());
                    realSendAmount = realSendAmount - remainSendAmount;
                } else {
                    newLogisticsGoods.setRealSendAmount(realSendAmount);
                    newLogisticsGoods.setLogisticsStatus(LogisticsStatusEnum.PART_SEND.getCode());
                    realSendAmount = 0;
                }
                logisticsGoodsMapper.insert(newLogisticsGoods);
                logisticsGoods.setGoodsAmount(logisticsGoods.getRealSendAmount());
                logisticsGoods.setLogisticsStatus(LogisticsStatusEnum.WAIT_RECEIVE.getCode());
                b = false;
            } else {
                logisticsGoods.setRealLogisticsNo(request.getRealLogisticsNo());
                logisticsGoods.setExpressCode(request.getLogisticsCompany());
                logisticsGoods.setRealWarehouse(request.getRealWarehouse());
            }
            logisticsGoodsMapper.updateById(logisticsGoods);
            if(logisticsGoods.getSelfFlag().equals(SelfFlagEnum.YES_SELF.getCode())){
                warehouseOut.add(logisticsGoods);
                goodsIds.add(logisticsGoods.getGoodsId().longValue());
            }
            Map<String, BigDecimal> map = getGoodsShouldRealSendAmount(request.getOrderId(), request.getGoodsId());
            if (map.get("goodsAmount").intValue() == map.get("realSendAmount").intValue()) {
                updateGoodsStatus(request.getOrderId(), request.getGoodsId(), LogisticsStatusEnum.WAIT_RECEIVE.getCode(),
                        request.getRemark());
            } else {
                updateGoodsStatus(request.getOrderId(), request.getGoodsId(), LogisticsStatusEnum.PART_SEND.getCode(),
                        request.getRemark());
            }
            updateLogisticsStatus(logisticsGoods.getLogisticsNo(),LogisticsStatusEnum.WAIT_RECEIVE.getCode());
            //插入记录
            asyncSendService.addLog(uid, name, logisticsGoods.getOrderNo(), "编辑发货：" + logisticsGoods.getGoodsName() + "，数量：" +
                    request.getRealSendAmount());
        }
        QueryWrapper<UserOrder> queryWrapper1 = new QueryWrapper<>();
        queryWrapper1.eq("id", request.getOrderId());
        UserOrder userOrder = userOrderMapper.selectOne(queryWrapper1);
        if (userOrder.getOrderStatus().equals(OrderStatusEnum.READY_TO_SHIP.getCode())
                ||(userOrder.getOrderStatus().equals(OrderStatusEnum.READY_TO_RECEIVE.getCode())&&userOrder.getConfirmTime()==null)) {
            updateOrderStatusAndConfirmTime(userOrder);
            //发送发货推送
            Map<String, String> expressMap = expressNameByCode();
            MessageTemplate messageTemplate = sendMessageHandler.getMessageTemplate(4);
            String appMessageContent = messageTemplate==null?"":messageTemplate.getSmtAppContent()
                        .replace("{}", expressMap.get(request.getLogisticsCompany()));
            String stationMessageContent = messageTemplate==null?"":messageTemplate.getSmtMessageContent()
                        .replace("{}", expressMap.get(request.getLogisticsCompany()));
            String smtShortContent = messageTemplate==null?"":messageTemplate.getSmtShortContent()
                    .replace("{$logisticsNo}",request.getRealLogisticsNo());
            sendMessageHandler.sendMessage(userOrder.getOrderNo(), appMessageContent, stationMessageContent, smtShortContent,
                    request.getRealLogisticsNo(), userOrder.getReceiverPhone(), logisticsGoodsList.get(0).getGoodsCoverImg(),
                    logisticsGoodsList.get(0).getBuyerId(), 4, BigDecimal.ZERO, BigDecimal.ZERO, "", (byte) 0);
        }
        //通知物料出库
        asyncSendService.noticeMaterial(warehouseOut,goodsIds,name,new ArrayList<>());
        return true;
    }

    /**
     * 自营待发货导入发货
     *
     * @param list
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public void excelImportHandler(List<SelfWaitSend> list, Long uid, String name) {
        selfWaitSendError.clear();
        if (list.isEmpty()) {
            return;
        }
        MessageTemplate messageTemplate = sendMessageHandler.getMessageTemplate(4);
        List<LogisticsGoods> sendGoodsList = new ArrayList<>();
        List<Long> goodsIds = new ArrayList<>();
        Map<String, Integer> orderGoodsMap = new HashMap<>();
        List<OrderGoods> orderGoodsList = new ArrayList<>();
        List<Integer> orderIds = new ArrayList<>();
        Map<String, String> expressMap = availableExpressMap();
        List<OrderLogistics> orderLogisticsList = new ArrayList<>();
        List<String> orderNoList = new ArrayList<>();
        List<JSONObject> addLogList = new ArrayList<>();
        List<SelfWaitSend> sendMessageList = new ArrayList<>();
        for (SelfWaitSend selfWaitSend : list) {
            if(selfWaitSend.getRealLogisticsNo()==null && selfWaitSend.getLogisticsCompany()==null){
                continue;
            }
            if (selfWaitSend.getRealLogisticsNo() == null || selfWaitSend.getLogisticsCompany() == null) {
                selfWaitSendError.add(selfWaitSend.getOrderNo()+"--运单号或快递公司为空");
                continue;
            }
            if (selfWaitSend.getGoodsAmount() < selfWaitSend.getRealSendAmount() || selfWaitSend.getRealSendAmount()==0) {
                selfWaitSendError.add(selfWaitSend.getOrderNo()+"--实发数量大于应发数量或实发数量为0");
                continue;
            }
            if(!expressMap.containsKey(selfWaitSend.getLogisticsCompany())){
                selfWaitSendError.add(selfWaitSend.getOrderNo()+"--快递公司名称错误");
                continue;
            }
            if (!selfWaitSendError.isEmpty()) {
                continue;
            }
            LogisticsGoods logisticsGoods = new LogisticsGoods();
            logisticsGoods.setSelfFlag(SelfFlagEnum.YES_SELF.getCode());
            logisticsGoods.setRealWarehouse(selfWaitSend.getWarehouseId());
            logisticsGoods.setLogisticsNo(selfWaitSend.getLogisticsNo());
            logisticsGoods.setRemark(selfWaitSend.getRemark()==null?"":selfWaitSend.getRemark());
            logisticsGoods.setReceiverName(selfWaitSend.getReceiverName());
            logisticsGoods.setReceiverPhone(selfWaitSend.getReceiverPhone());
            logisticsGoods.setReceiverAddress(selfWaitSend.getReceiverAddress());
            logisticsGoods.setRealSendAmount(selfWaitSend.getRealSendAmount());
            logisticsGoods.setRealLogisticsNo(selfWaitSend.getRealLogisticsNo());
            logisticsGoods.setExpressCode(expressMap.get(selfWaitSend.getLogisticsCompany()));
            logisticsGoods.setGoodsId(selfWaitSend.getGoodsId());
            logisticsGoods.setOrderNo(selfWaitSend.getOrderNo());
            logisticsGoods.setBuyerId(selfWaitSend.getBuyId());
            orderIds.add(selfWaitSend.getOrderId());
            OrderGoods orderGoods = new OrderGoods();
            orderGoods.setGoodsId(selfWaitSend.getGoodsId());
            orderGoods.setOrderNo(selfWaitSend.getOrderNo());
            orderGoods.setRemark(logisticsGoods.getRemark()==null?"":logisticsGoods.getRemark());
            if (orderGoodsMap.containsKey(selfWaitSend.getOrderNo() + selfWaitSend.getGoodsId())) {
                orderGoods.setRealSendAmount(orderGoodsMap.get(selfWaitSend.getOrderNo() + selfWaitSend.getGoodsId()) + selfWaitSend.getRealSendAmount());
                orderGoodsList = orderGoodsList.stream().filter(g -> !(g.getOrderNo() + g.getGoodsId()).equals(selfWaitSend.getOrderNo() + selfWaitSend.getGoodsId())).collect(Collectors.toList());
                orderGoodsMap.remove(selfWaitSend.getOrderNo() + selfWaitSend.getGoodsId());
                orderGoodsMap.put(selfWaitSend.getOrderNo() + selfWaitSend.getGoodsId(),orderGoods.getRealSendAmount());
            } else {
                orderGoodsMap.put(selfWaitSend.getOrderNo() + selfWaitSend.getGoodsId(), selfWaitSend.getRealSendAmount());
                orderGoods.setRealSendAmount(selfWaitSend.getRealSendAmount());
            }
            orderGoods.setOrderId(selfWaitSend.getOrderId());
            OrderLogistics orderLogistics = new OrderLogistics();
            orderLogistics.setLogisticsNo(selfWaitSend.getLogisticsNo());
            if (selfWaitSend.getGoodsAmount().equals(selfWaitSend.getRealSendAmount())) {
                logisticsGoods.setLogisticsStatus(LogisticsStatusEnum.WAIT_RECEIVE.getCode());
            } else if (selfWaitSend.getGoodsAmount() > selfWaitSend.getRealSendAmount() && selfWaitSend.getRealSendAmount() > 0) {
                logisticsGoods.setLogisticsStatus(LogisticsStatusEnum.PART_SEND.getCode());
            }
            orderLogistics.setLogisticsStatus(LogisticsStatusEnum.WAIT_RECEIVE.getCode());
            orderLogisticsList.add(orderLogistics);
            orderGoodsList.add(orderGoods);
            sendGoodsList.add(logisticsGoods);
            goodsIds.add(selfWaitSend.getGoodsId().longValue());
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("uid",uid);
            jsonObject.put("name",name);
            jsonObject.put("orderNo",selfWaitSend.getOrderNo());
            jsonObject.put("goodsId",selfWaitSend.getGoodsId());
            jsonObject.put("log","excel批量导入自营发货：" + selfWaitSend.getGoodsName()+"，数量："+selfWaitSend.getRealSendAmount());
            addLogList.add(jsonObject);
            sendMessageList.add(selfWaitSend);
            orderNoList.add(selfWaitSend.getOrderNo());
        }
        //修改数据库操作
//        asyncSendService.selfSendBatchUpdate(orderLogisticsList,orderIds,orderGoodsList,sendGoodsList,selfWaitSendError);
        asyncSendService.selfUpdateLogisticsGoods(sendGoodsList,selfWaitSendError);
        asyncSendService.selfUpdateOrderLogistics(orderLogisticsList,selfWaitSendError);
        asyncSendService.selfUpdateOrderGoods(orderGoodsList,selfWaitSendError);
        asyncSendService.selfBatchUpdateOrderStatusAndConfirmTime(orderIds,selfWaitSendError);
        //通知物料出库
        asyncSendService.noticeMaterial(sendGoodsList,goodsIds,name,selfWaitSendError);
        //记录订单日志
        asyncSendService.batchAddLog(addLogList,selfWaitSendError);
        //发送推送通知
        asyncSendService.batchSelfSendMessage(messageTemplate,sendMessageList,selfWaitSendError);
    }

//    /**
//     * 请求需要导入商品的所有图片
//     *
//     * @param goodsIds
//     * @return
//     */
//    public Map<Integer, String> goodsCoverImgMap(List<Integer> goodsIds) {
//        if (goodsIds.isEmpty()) {
//            return new HashMap<>();
//        }
//        QueryWrapper<LogisticsGoods> queryWrapper = new QueryWrapper<>();
//        queryWrapper.in("goods_id", goodsIds).groupBy("goods_id").orderByDesc("create_time");
//        List<LogisticsGoods> list = logisticsGoodsMapper.selectList(queryWrapper);
//        return list.stream().collect(Collectors.toMap(LogisticsGoods::getGoodsId, LogisticsGoods::getGoodsCoverImg));
//
//    }

    /**
     * 批量修改真实物流单号
     *
     * @param list
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public void batchUpdateRealLogisticsNoExcelImportHandler(List<BatchUpdateRealLogisticsNo> list, Long uid, String name) {
        updateLogisticsNoError.clear();
        if (list.isEmpty()) {
            return;
        }
        Map<String, String> expressMap = allExpressMap();
        for (BatchUpdateRealLogisticsNo batchUpdateRealLogisticsNo : list) {
            if(batchUpdateRealLogisticsNo.getOldRealLogisticsNo().contains("原运单号")){
                continue;
            }
            if(batchUpdateRealLogisticsNo.getExpressCompany()==null
                    || batchUpdateRealLogisticsNo.getNewRealLogisticsNo()==null
                    || batchUpdateRealLogisticsNo.getOldRealLogisticsNo()==null){
                updateLogisticsNoError.add(batchUpdateRealLogisticsNo.getOrderNo());
                continue;
            }
            if(!expressMap.containsKey(batchUpdateRealLogisticsNo.getExpressCompany())){
                updateLogisticsNoError.add(batchUpdateRealLogisticsNo.getOrderNo());
                continue;
            }
            QueryWrapper<LogisticsGoods> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("real_logistics_no",batchUpdateRealLogisticsNo.getOldRealLogisticsNo())
                    .eq("order_no",batchUpdateRealLogisticsNo.getOrderNo());
            Integer count  = logisticsGoodsMapper.selectCount(queryWrapper);
            if(count==0){
                updateLogisticsNoError.add(batchUpdateRealLogisticsNo.getOrderNo());
                continue;
            }
            if(!updateLogisticsNoError.isEmpty()){
                continue;
            }
            batchUpdateRealLogisticsNo.setExpressCompany(expressMap.get(batchUpdateRealLogisticsNo.getExpressCompany()));
            addLog(uid, name, batchUpdateRealLogisticsNo.getOrderNo(), "更新单号");
            //请求物料修改接口
            ShipingCodeDto shipingCodeDto = new ShipingCodeDto();
            shipingCodeDto.setType(1);
            shipingCodeDto.setNewShippingCode(batchUpdateRealLogisticsNo.getNewRealLogisticsNo());
            shipingCodeDto.setOldShippingCode(batchUpdateRealLogisticsNo.getOldRealLogisticsNo());
            shipingCodeDto.setUserId(uid.toString());
            shipingCodeDto.setUserName(name);
            shipingCodeDto.setOrderCode(batchUpdateRealLogisticsNo.getOrderNo());
            iChangeLogisticsNoService.changeShippingCodeService(shipingCodeDto);
        }
        if(updateLogisticsNoError.isEmpty()){
            logisticsGoodsMapper.batchUpdateRealLogisticsNo(list);
        }
    }


    /**
     * 确认收货
     *
     * @param orderNo
     * @return
     */
    public boolean confirmReceive(String orderNo) {
        QueryWrapper<LogisticsGoods> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("order_no", orderNo);
        List<LogisticsGoods> list = logisticsGoodsMapper.selectList(queryWrapper);
        for (LogisticsGoods logisticsGoods : list) {
            logisticsGoods.setLogisticsStatus(LogisticsStatusEnum.CONFIRM_RECEIVE.getCode());
            logisticsGoodsMapper.updateById(logisticsGoods);
//            Byte status = logisticsStatus(logisticsGoods.getLogisticsNo(), logisticsGoods.getOrderId().toString(), logisticsGoods.getGoodsId().toString(), LogisticsStatusEnum.CONFIRM_RECEIVE.getCode());
            updateLogisticsStatus(logisticsGoods.getLogisticsNo(), LogisticsStatusEnum.CONFIRM_RECEIVE.getCode());
        }
        return true;
    }


    /**
     * 判断包裹状态
     *
     * @param logisticsNo
     * @return
     */
    public Byte logisticsStatus(String logisticsNo, String orderId, String goodsId, Byte LogisticsStatus) {
        QueryWrapper<LogisticsGoods> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("logistics_no", logisticsNo).eq("del_flag", 0);
        List<LogisticsGoods> list = logisticsGoodsMapper.selectList(queryWrapper);
        for (LogisticsGoods logisticsGoods : list) {
            if (logisticsGoods.getGoodsId().toString().equals(goodsId) &&
                    logisticsGoods.getOrderId().toString().equals(orderId)) {
                logisticsGoods.setLogisticsStatus(LogisticsStatus);
            }
        }
        if (list.size() == 1) {
            return list.get(0).getLogisticsStatus();
        }
        List<Byte> logisticsStatusList = list.stream().map(LogisticsGoods::getLogisticsStatus).collect(Collectors.toList());
        if (logisticsStatusList.contains(LogisticsStatusEnum.PART_SEND.getCode())) {
            return LogisticsStatusEnum.PART_SEND.getCode();
        } else if (!logisticsStatusList.contains(LogisticsStatusEnum.PART_SEND.getCode())) {
            if (logisticsStatusList.contains(LogisticsStatusEnum.WAIT_SEND.getCode()) &&
                    logisticsStatusList.contains(LogisticsStatusEnum.WAIT_RECEIVE.getCode())) {
                return LogisticsStatusEnum.PART_SEND.getCode();
            } else if (logisticsStatusList.contains(LogisticsStatusEnum.WAIT_SEND.getCode()) &&
                    logisticsStatusList.contains(LogisticsStatusEnum.CONFIRM_RECEIVE.getCode())) {
                return LogisticsStatusEnum.PART_SEND.getCode();
            } else if (!logisticsStatusList.contains(LogisticsStatusEnum.WAIT_SEND.getCode()) &&
                    logisticsStatusList.contains(LogisticsStatusEnum.WAIT_RECEIVE.getCode()) &&
                    logisticsStatusList.contains(LogisticsStatusEnum.CONFIRM_RECEIVE.getCode())) {
                return LogisticsStatusEnum.WAIT_RECEIVE.getCode();
            } else if (!logisticsStatusList.contains(LogisticsStatusEnum.WAIT_SEND.getCode()) &&
                    !logisticsStatusList.contains(LogisticsStatusEnum.WAIT_RECEIVE.getCode()) &&
                    logisticsStatusList.contains(LogisticsStatusEnum.CONFIRM_RECEIVE.getCode())) {
                return LogisticsStatusEnum.CONFIRM_RECEIVE.getCode();
            } else if (!logisticsStatusList.contains(LogisticsStatusEnum.WAIT_SEND.getCode()) &&
                    logisticsStatusList.contains(LogisticsStatusEnum.WAIT_RECEIVE.getCode()) &&
                    !logisticsStatusList.contains(LogisticsStatusEnum.CONFIRM_RECEIVE.getCode())) {
                return LogisticsStatusEnum.WAIT_RECEIVE.getCode();
            } else if (logisticsStatusList.contains(LogisticsStatusEnum.WAIT_SEND.getCode()) &&
                    !logisticsStatusList.contains(LogisticsStatusEnum.WAIT_RECEIVE.getCode()) &&
                    !logisticsStatusList.contains(LogisticsStatusEnum.CONFIRM_RECEIVE.getCode())) {
                return LogisticsStatusEnum.WAIT_SEND.getCode();
            } else {
                return LogisticsStatusEnum.WAIT_SEND.getCode();
            }
        }
        return -1;
    }

    /**
     * 统计某订单下某商品应发实发数量
     *
     * @return
     */
    public Map<String, BigDecimal> getGoodsShouldRealSendAmount(Integer orderId, Integer goodsId) {
        return logisticsGoodsMapper.getGoodsShouldRealSendAmount(orderId, goodsId);
    }

    /**
     * 修改订单商品状态
     *
     * @param orderId
     * @param goodsId
     * @param status
     */
    public void updateGoodsStatus(Integer orderId, Integer goodsId, Byte status, String remark) {
        QueryWrapper<OrderGoods> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("order_id", orderId).eq("goods_id", goodsId);
        OrderGoods orderGoods = orderGoodsMapper.selectOne(queryWrapper);
        orderGoods.setGoodsStatus(status);
        if (remark != null && !remark.trim().isEmpty()) {
            if(orderGoods.getRemark()!=null && !orderGoods.getRemark().isEmpty()){
                orderGoods.setRemark(orderGoods.getRemark()+"，"+remark);
            }else{
                orderGoods.setRemark(remark);
            }
        }
        Map<String, BigDecimal> map = logisticsGoodsMapper.getGoodsShouldRealSendAmount(orderId, goodsId);
        orderGoods.setRealSendAmount(map.get("realSendAmount").intValue());
        orderGoodsMapper.updateById(orderGoods);
    }

    /**
     * 修改订单状态以及自动确认收货时间
     *
     */
    public void updateOrderStatusAndConfirmTime(UserOrder userOrder) {
        userOrder.setOrderStatus(OrderStatusEnum.READY_TO_RECEIVE.getCode());
        userOrder.setConfirmTime(DateUtil.getDateAfterMinute(new Date(),
                Integer.parseInt(timeConfiguration.getConfirmTimeMinutes())));
        userOrderMapper.updateById(userOrder);
    }

    /**
     * 批量修改订单状态以及自动确认收货时间
     *
     * @param orderIds
     */
//    public void batchUpdateOrderStatusAndConfirmTime(List<Integer> orderIds) {
//        UpdateWrapper<UserOrder> userOrderUpdateWrapper = new UpdateWrapper<>();
//        userOrderUpdateWrapper.in("id", orderIds)
//                .and(q->q.eq("order_status",OrderStatusEnum.READY_TO_SHIP.getCode()).or()
//                        .eq("order_status",OrderStatusEnum.READY_TO_RECEIVE.getCode()).isNull("confirm_time"));
////        .eq("order_status", OrderStatusEnum.READY_TO_RECEIVE.getCode());
//        UserOrder userOrder = new UserOrder();
//        userOrder.setOrderStatus(OrderStatusEnum.READY_TO_RECEIVE.getCode());
//        userOrder.setConfirmTime(DateUtil.getDateAfterMinute(new Date(),
//                Integer.parseInt(timeConfiguration.getConfirmTimeMinutes())));
//        userOrderMapper.update(userOrder, userOrderUpdateWrapper);
//    }

    /**
     * 修改包裹状态
     *
     * @param logisticsNo
     * @param status
     */
    public void updateLogisticsStatus(String logisticsNo, Byte status) {
        QueryWrapper<OrderLogistics> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("logistics_no", logisticsNo).eq("del_flag",0);
        OrderLogistics orderLogistics = new OrderLogistics();
        orderLogistics.setLogisticsStatus(status);
        orderLogisticsMapper.update(orderLogistics,queryWrapper);
    }

    /**
     * 取消或者删除订单后或者订单退款删除该订单已产生包裹以及商品
     *
     * @param orderId
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean cancelLogistics(Integer orderId) {
        QueryWrapper<LogisticsGoods> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("del_flag", 0).eq("order_id", orderId);
        List<LogisticsGoods> logisticsGoodsList = logisticsGoodsMapper.selectList(queryWrapper);
        List<String> logisticsNoList = logisticsGoodsList.stream().map(LogisticsGoods::getLogisticsNo).collect(Collectors.toList());
        if (logisticsNoList.isEmpty()) {
            return true;
        }
        logisticsGoodsMapper.batchUpdateDelByOrderId(logisticsGoodsList);
        Set<String> set = new HashSet<>(logisticsNoList);
        List<String> tempList = new ArrayList<>(set);
        for (String s : set) {
            if (isHaveGoods(s)) {
                tempList.remove(s);
            }
        }
        if (!tempList.isEmpty()) {
            orderLogisticsMapper.batchUpdateDel(tempList);
        }
        return true;
    }

    /**
     * 单个商品退款删除该订单下的包裹的商品
     *
     * @param orderId
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean cancelLogisticsAndGoods(Integer orderId, Integer goodsId) {
        QueryWrapper<LogisticsGoods> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("del_flag", 0).eq("order_id", orderId).eq("goods_id", goodsId)
                .eq("logistics_status", LogisticsStatusEnum.WAIT_SEND.getCode());
        List<LogisticsGoods> logisticsGoodsList = logisticsGoodsMapper.selectList(queryWrapper);
        if (logisticsGoodsList.isEmpty()) {
            return true;
        }
        //修改包裹状态
        for (LogisticsGoods logisticsGoods : logisticsGoodsList) {
            logisticsGoods.setDelFlag((byte) 1);
            logisticsGoodsMapper.updateById(logisticsGoods);
            if (isHaveGoods(logisticsGoods.getLogisticsNo())) {
                updateLogisticsStatus(logisticsGoods.getLogisticsNo(),
                        logisticsStatus(logisticsGoods.getLogisticsNo(),
                                logisticsGoods.getOrderId().toString(),
                                logisticsGoods.getGoodsId().toString(),
                                LogisticsStatusEnum.CONFIRM_RECEIVE.getCode()));
                continue;
            }
            UpdateWrapper<OrderLogistics> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("logistics_no", logisticsGoods.getLogisticsNo());
            OrderLogistics orderLogistics = new OrderLogistics();
            orderLogistics.setDelFlag((byte) 1);
            orderLogisticsMapper.update(orderLogistics, updateWrapper);
        }
        return true;
    }


    /**
     * 判断包裹是否为空包裹
     *
     * @param logisticsNo
     * @return
     */
    public boolean isHaveGoods(String logisticsNo) {
        QueryWrapper<LogisticsGoods> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("del_flag", 0).eq("logistics_no", logisticsNo);
        return logisticsGoodsMapper.selectCount(queryWrapper) > 0;
    }

    /**
     * 根据订单ID，商品ID 返回真实物流单号
     *
     * @param orderId
     * @param goodsId
     * @return
     */
    public String realLogisticsNo(Integer orderId, Integer goodsId) {
        QueryWrapper<LogisticsGoods> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("order_id", orderId).eq("goods_id", goodsId);
        return logisticsGoodsMapper.selectList(queryWrapper).stream()
                .filter(l->!l.getRealLogisticsNo().isEmpty()&& l.getRealLogisticsNo()!=null)
                .map(LogisticsGoods::getRealLogisticsNo).collect(Collectors.joining(";"));
    }

    /**
     * 根据订单编号以及商品ID获取部分发货或者全部发货的真实物流单号
     *
     * @param request
     * @return
     */
    public Set<String> realLogisticsNoList(UpdateRealLogisticsNoRequest request) {
        QueryWrapper<LogisticsGoods> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("del_flag", 0)
                .in("logistics_status", LogisticsStatusEnum.PART_SEND.getCode(), LogisticsStatusEnum.WAIT_RECEIVE.getCode())
                .eq("order_no", request.getOrderNo())
                .eq("goods_id", request.getGoodsId());
        List<LogisticsGoods> list = logisticsGoodsMapper.selectList(queryWrapper);
        return list.stream().map(LogisticsGoods::getRealLogisticsNo)
                .collect(Collectors.toSet());
    }


    /**
     * 修改真实物流单号
     *
     * @param request
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateRealLogisticsNo(UpdateRealLogisticsNoRequest request, Long uid, String name) {
        UpdateWrapper<LogisticsGoods> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("order_no", request.getOrderNo()).eq("del_flag", 0)
                .eq("goods_id", request.getGoodsId())
                .eq("real_logistics_no", request.getOldRealLogisticsNo());
        LogisticsGoods logisticsGoods = new LogisticsGoods();
        logisticsGoods.setRealLogisticsNo(request.getNewRealLogisticsNo());
        logisticsGoods.setExpressCode(request.getNewExpressCompany());
        addLog(uid, name, request.getOrderNo(), "单号更新");
        //请求接口通知物料修改
        ShipingCodeDto shipingCodeDto = new ShipingCodeDto();
        shipingCodeDto.setType(1);
        shipingCodeDto.setNewShippingCode(request.getNewRealLogisticsNo());
        shipingCodeDto.setOldShippingCode(request.getOldRealLogisticsNo());
        shipingCodeDto.setUserId(uid.toString());
        shipingCodeDto.setUserName(name);
        shipingCodeDto.setOrderCode(request.getOrderNo());
        iChangeLogisticsNoService.changeShippingCodeService(shipingCodeDto);
        return logisticsGoodsMapper.update(logisticsGoods, updateWrapper) > 0;
    }

//    /**
//     * 通知物料出库 包裹
//     *
//     * @param paramList
//     */
//    public void noticeMaterialByLogisticsNo(List<NoticeMaterialRequest> paramList) {
//        if (paramList.isEmpty()) {
//            return;
//        }
//        List<String> list = paramList.stream().map(NoticeMaterialRequest::getLogisticsNo).collect(Collectors.toList());
//        //查询出有真实物流单号的所有商品
//        QueryWrapper<LogisticsGoods> queryWrapper = new QueryWrapper<>();
//        queryWrapper.eq("del_flag", 0).eq("is_wdt_push",1).in("logistics_no", list);
//        List<LogisticsGoods> goodsList = logisticsGoodsMapper.selectList(queryWrapper);
//        if (goodsList.isEmpty()) {
//            return;
//        }
//        //修改真实物流信息
//        List<LogisticsGoods> goods = new ArrayList<>();
//        List<OrderLogistics> logistics = new ArrayList<>();
//        List<OrderGoods> orderGoodsList = new ArrayList<>();
//        List<Integer> orderIds = new ArrayList<>();
//        List<UserOrder> userOrderList = new ArrayList<>();
//        Map<String, String> expressMap = allExpressMap();
//        for (NoticeMaterialRequest request : paramList) {
//            List<LogisticsGoods> logisticsGoodsList = goodsList.stream()
//                    .filter(g->g.getLogisticsNo().equals(request.getLogisticsNo())).collect(Collectors.toList());
//            for(LogisticsGoods logisticsGoods:logisticsGoodsList){
//                if (expressMap.containsKey(request.getExpressCompany())) {
//                    logisticsGoods.setExpressCode(expressMap.get(request.getExpressCompany()));
//                }
//                logisticsGoods.setRealLogisticsNo(request.getRealLogisticsNo());
//                logisticsGoods.setLogisticsNo(request.getLogisticsNo());
//                logisticsGoods.setLogisticsStatus(LogisticsStatusEnum.WAIT_RECEIVE.getCode());
//                goods.add(logisticsGoods);
//                OrderLogistics orderLogistics = new OrderLogistics();
//                orderLogistics.setLogisticsNo(request.getLogisticsNo());
//                orderLogistics.setLogisticsStatus(LogisticsStatusEnum.WAIT_RECEIVE.getCode());
//                logistics.add(orderLogistics);
//                OrderGoods orderGoods = new OrderGoods();
//                orderGoods.setGoodsId(logisticsGoods.getGoodsId());
//                orderGoods.setOrderId(logisticsGoods.getOrderId());
//                orderGoods.setGoodsStatus(LogisticsStatusEnum.WAIT_RECEIVE.getCode());
//                orderGoods.setRealSendAmount(logisticsGoods.getGoodsAmount());
//                orderGoodsList.add(orderGoods);
//                if(!orderIds.contains(logisticsGoods.getOrderId())){
//                    UserOrder userOrder = new UserOrder();
//                    userOrder.setId(logisticsGoods.getOrderId());
//                    userOrder.setConfirmTime(DateUtil.getDateAfterMinute(new Date(),
//                            Integer.parseInt(timeConfiguration.getConfirmTimeMinutes())));
//                    userOrderList.add(userOrder);
//                }
//            }
//        }
//        //修改包裹商品状态
//        logisticsGoodsMapper.batchUpdateSend(goods);
//        //修改包裹状态
//        orderLogisticsMapper.batchUpdateLogisticsStatus(logistics);
//        //修改商品状态
//        orderGoodsMapper.batchUpdateGoodsStatusWdtPush(orderGoodsList);
//        //修改订单确认收货时间
//        userOrderMapper.batchUpdateOrderConfirmTime(userOrderList);
//        //通知物料出库
//        noticeMaterial(goodsList,);
//    }

    /**
     * 通知物料出库
     *
     * @param goodsList
     */
//    public void noticeMaterial(List<LogisticsGoods> goodsList,String name) {
//        if (goodsList.isEmpty()) {
//            return;
//        }
//        //筛选出自营商品需要出库
//        goodsList = goodsList.stream().filter(g->g.getSelfFlag().equals(SelfFlagEnum.YES_SELF.getCode())).collect(Collectors.toList());
//        if(goodsList.isEmpty()){
//            return;
//        }
//        //获取物料信息
//        Map<Integer, GoodsSkuMaterialDTO> materialDTOMap = getMaterialMap(goodsList);
//        //获取买家信息
//        Map<Long, JmUserReponse> buyerMap = getJmUserMap(goodsList);
////        List<JmOrderWarehouseOutVo> list = new ArrayList<>();
//        for (LogisticsGoods logisticsGoods : goodsList) {
//            JmUserReponse jmUserReponse = null;
//            GoodsSkuMaterialDTO goodsSkuMaterialDTO = null;
//            JmOrderWarehouseOutVo jmOrderWarehouseOutVo = new JmOrderWarehouseOutVo();
//            if (materialDTOMap.containsKey(logisticsGoods.getGoodsId())) {
//                goodsSkuMaterialDTO = materialDTOMap.get(logisticsGoods.getGoodsId());
//            }
//            if (buyerMap.containsKey(logisticsGoods.getBuyerId())) {
//                jmUserReponse = buyerMap.get(logisticsGoods.getBuyerId());
//            }
//            jmOrderWarehouseOutVo.setOrderSn(logisticsGoods.getOrderNo());
//            if (jmUserReponse == null) {
//                jmOrderWarehouseOutVo.setBuyerMessage("");
//            } else {
//                jmOrderWarehouseOutVo.setBuyerMessage(jmUserReponse.getName() +" "+jmUserReponse.getMobile());
//            }
//            jmOrderWarehouseOutVo.setX(logisticsGoods.getRealSendAmount());
//            jmOrderWarehouseOutVo.setBuyerDetail(logisticsGoods.getReceiverName()
//                    + logisticsGoods.getReceiverPhone() + " " + logisticsGoods.getReceiverAddress());
//            jmOrderWarehouseOutVo.setMaterialSkuRelationshipDTOList(goodsSkuMaterialDTO != null ?
//                    goodsSkuMaterialDTO.getMaterialSkuRelationship() : new ArrayList<>());
//            jmOrderWarehouseOutVo.setSupplierId(logisticsGoods.getSupplierId());
//            jmOrderWarehouseOutVo.setShippingCode(logisticsGoods.getRealLogisticsNo());
//            jmOrderWarehouseOutVo.setSendWarehouseId(logisticsGoods.getRealWarehouse());
//            jmOrderWarehouseOutVo.setOperator(name);
//            jmOrderWarehouseOutVo.setRemark(logisticsGoods.getRemark()==null?"":logisticsGoods.getRemark());
////            list.add(jmOrderWarehouseOutVo);
//            try {
//                Message sendMessage = new Message("orderOut", "", "", JSON.toJSONBytes(jmOrderWarehouseOutVo));
//                producerBean.send(sendMessage);
//                log.info("发送订单物料出库队列成功 [{}]",JSON.toJSONString(jmOrderWarehouseOutVo));
//            } catch (Exception e) {
//                log.info("发送订单物料出库队列失败 [{}]",e.getMessage());
//            }
//        }
//        //发送队列
////        iMaterialService.add(list);
//
//    }

//    /**
//     * 获取买家信息
//     *
//     * @param goodsList
//     * @return
//     */
//    public Map<Long, JmUserReponse> getJmUserMap(List<LogisticsGoods> goodsList) {
//        //获取买家信息
//        List<JmUserReponse> jmUserResponseList = iMemberService.getMemberByUids(goodsList.stream()
//                .map(a -> a.getBuyerId().intValue()).collect(Collectors.toList())).getData();
//        Map<Long, JmUserReponse> map = new HashMap<>(jmUserResponseList.size());
//        for (JmUserReponse jmUserReponse : jmUserResponseList) {
//            map.put(jmUserReponse.getId().longValue(), jmUserReponse);
//        }
//        return map;
//    }

    /**
     * 获取物料信息
     *
     * @param goodsId
     * @return
     */
//    public Map<Integer, GoodsSkuMaterialDTO> getMaterialMap(List<Long> goodsId) {
//        //请求接口获取物料信息
//        List<GoodsSkuMaterialDTO> materialDTOS = basicDataService.getMaterialSkuRelationshipByIds(goodsId);
//        return materialDTOS.stream().distinct().collect(Collectors.toMap(g->g.getSkuId().intValue(),g->g,(oldValue, newValue)->newValue));
//    }

    /**
     * 全部快递公司信息
     *
     * @return
     */
    public Map<String, String> allExpressMap() {
        return iExpressService.selectExpressList()
                .stream().filter(e -> e.getExpressCode() != null)
                .collect(Collectors.toMap(ExpressDataDTO::getExpressName, ExpressDataDTO::getExpressCode));
    }

    /**
     * 可用快递公司信息
     * @return
     */
    public Map<String, String> availableExpressMap() {
        return iExpressService.selectExpressList()
                .stream().filter(e -> e.getExpressCode() != null && e.getStatus()==1 && e.getIsDel()==0)
                .collect(Collectors.toMap(ExpressDataDTO::getExpressName, ExpressDataDTO::getExpressCode));
    }

    /**
     * 快递公司信息
     *
     * @return
     */
    public Map<String, String> expressNameByCode() {
        return iExpressService.selectExpressList()
                .stream().filter(e -> e.getExpressCode() != null)
                .collect(Collectors.toMap(ExpressDataDTO::getExpressCode, ExpressDataDTO::getExpressName));
    }

    /**
     * 部分发货EXCEL导入发货
     *
     * @param list
     * @param uid
     * @param name
     */
    @Transactional(rollbackFor = Exception.class)
    public void partSend(List<ExportOrderAllResponse> list, Long uid, String name) {
        partSendError.clear();
        if (list.isEmpty()) {
            return;
        }
        List<String> orderNos = list.stream().map(ExportOrderAllResponse::getOrderNo).collect(Collectors.toList());
        //获取订单商品
        QueryWrapper<OrderGoods> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("order_no", orderNos).in("goods_status", LogisticsStatusEnum.PART_SEND.getCode(),
                LogisticsStatusEnum.WAIT_SEND.getCode());
        List<OrderGoods> orderGoodsList = orderGoodsMapper.selectList(queryWrapper);
        //获取包裹商品
        QueryWrapper<LogisticsGoods> queryWrapper1 = new QueryWrapper<>();
        queryWrapper1.in("order_no", orderNos).in("logistics_status", LogisticsStatusEnum.PART_SEND.getCode(),
                LogisticsStatusEnum.WAIT_SEND.getCode());
        List<LogisticsGoods> logisticsGoodsList = logisticsGoodsMapper.selectList(queryWrapper1);
        List<OrderGoods> goodsList = new ArrayList<>();
        List<LogisticsGoods> updateLogisticsGoodsList = new ArrayList<>();
        List<LogisticsGoods> insertLogisticsGoodsList = new ArrayList<>();
        List<LogisticsGoods> noticeMaterialOut = new ArrayList<>();
        List<Long> goodsIds = new ArrayList<>();
        Map<String, String> expressMap = availableExpressMap();
        List<JSONObject> addLogList = new ArrayList<>();
        for (ExportOrderAllResponse exportOrderAllResponse : list) {
            Integer realSendAmount = exportOrderAllResponse.getRealSendAmount();
            if (exportOrderAllResponse.getRealLogisticsNo() == null && exportOrderAllResponse.getExpressCompany()==null) {
                continue;
            }
            List<OrderGoods> og = orderGoodsList.stream()
                    .filter(g->g.getOrderNo().equals(exportOrderAllResponse.getOrderNo()) &&
                            g.getGoodsId().equals(exportOrderAllResponse.getGoodsId())).collect(Collectors.toList());
            List<LogisticsGoods> lg = logisticsGoodsList.stream()
                    .filter(g->g.getOrderNo().equals(exportOrderAllResponse.getOrderNo()) &&
                            g.getGoodsId().equals(exportOrderAllResponse.getGoodsId())).collect(Collectors.toList());

            if (og.isEmpty() || lg.isEmpty()) {
                continue;
            }
            if(exportOrderAllResponse.getRealLogisticsNo() == null || exportOrderAllResponse.getExpressCompany()==null){
                partSendError.add(exportOrderAllResponse.getOrderNo()+"--运单号或快递公司为空");
                continue;
            }
            if (exportOrderAllResponse.getGoodsAmount()<exportOrderAllResponse.getRealSendAmount() ) {
                partSendError.add(exportOrderAllResponse.getOrderNo()+"--实发数量大于应发数量或实发数量为0");
                continue;
            }
            if(!expressMap.containsKey(exportOrderAllResponse.getExpressCompany())){
                partSendError.add(exportOrderAllResponse.getOrderNo()+"--快递公司名称错误");
                continue;
            }
            if (!partSendError.isEmpty()) {
                continue;
            }
            OrderGoods orderGoods = og.get(0);
            if(orderGoods.getGoodsAmount()-orderGoods.getRealSendAmount()!=exportOrderAllResponse.getRealSendAmount()){
                orderGoods.setGoodsStatus(LogisticsStatusEnum.PART_SEND.getCode());
            }else{
                orderGoods.setGoodsStatus(LogisticsStatusEnum.WAIT_RECEIVE.getCode());
            }
            orderGoods.setRemark(exportOrderAllResponse.getRemark()==null?"":exportOrderAllResponse.getRemark());
            orderGoods.setRealSendAmount(orderGoods.getRealSendAmount()+exportOrderAllResponse.getRealSendAmount());
            goodsList.add(orderGoods);
            for(LogisticsGoods logisticsGoods:lg){
                if(exportOrderAllResponse.getRealSendAmount()==0){
                    continue;
                }
                if(logisticsGoods.getLogisticsStatus().equals(LogisticsStatusEnum.WAIT_SEND.getCode())){
                    logisticsGoods.setRealLogisticsNo(exportOrderAllResponse.getRealLogisticsNo());
                    logisticsGoods.setExpressCode(expressMap.get(exportOrderAllResponse.getExpressCompany()));
                    logisticsGoods.setRemark(exportOrderAllResponse.getRemark());
                    if(logisticsGoods.getGoodsAmount()-logisticsGoods.getRealSendAmount()>exportOrderAllResponse.getRealSendAmount()){
                        logisticsGoods.setLogisticsStatus(LogisticsStatusEnum.PART_SEND.getCode());
                        logisticsGoods.setRealSendAmount(exportOrderAllResponse.getRealSendAmount());
                    }else{
                        logisticsGoods.setLogisticsStatus(LogisticsStatusEnum.WAIT_RECEIVE.getCode());
                        logisticsGoods.setRealSendAmount(logisticsGoods.getGoodsAmount());
                    }
                    logisticsGoods.setRemark(exportOrderAllResponse.getRemark()==null?"":exportOrderAllResponse.getRemark());
                    exportOrderAllResponse.setRealSendAmount(exportOrderAllResponse.getRealSendAmount()-logisticsGoods.getRealSendAmount());
                    updateLogisticsGoodsList.add(logisticsGoods);
                    if(orderGoods.getSelfFlag().equals(SelfFlagEnum.YES_SELF.getCode())){
                        noticeMaterialOut.add(logisticsGoods);
                    }
                }else{
                    LogisticsGoods newLogisticsGoods = new LogisticsGoods();
                    BeanUtils.copyProperties(logisticsGoods,newLogisticsGoods);
                    newLogisticsGoods.setRealLogisticsNo(exportOrderAllResponse.getRealLogisticsNo());
                    newLogisticsGoods.setExpressCode(expressMap.get(exportOrderAllResponse.getExpressCompany()));
                    newLogisticsGoods.setGoodsAmount(logisticsGoods.getGoodsAmount()-logisticsGoods.getRealSendAmount());
                    if(logisticsGoods.getGoodsAmount()-logisticsGoods.getRealSendAmount()>exportOrderAllResponse.getRealSendAmount()){
                        newLogisticsGoods.setLogisticsStatus(LogisticsStatusEnum.PART_SEND.getCode());
                    }else{
                        newLogisticsGoods.setLogisticsStatus(LogisticsStatusEnum.WAIT_RECEIVE.getCode());
                    }
                    newLogisticsGoods.setRemark(exportOrderAllResponse.getRemark()==null?"":exportOrderAllResponse.getRemark());
                    newLogisticsGoods.setRealSendAmount(exportOrderAllResponse.getRealSendAmount());
                    exportOrderAllResponse.setRealSendAmount(exportOrderAllResponse.getRealSendAmount()-newLogisticsGoods.getGoodsAmount());
                    logisticsGoods.setLogisticsStatus(LogisticsStatusEnum.WAIT_RECEIVE.getCode());
                    logisticsGoods.setGoodsAmount(logisticsGoods.getRealSendAmount());
                    updateLogisticsGoodsList.add(logisticsGoods);
                    insertLogisticsGoodsList.add(newLogisticsGoods);
                    if(orderGoods.getSelfFlag().equals(SelfFlagEnum.YES_SELF.getCode())){
                        noticeMaterialOut.add(newLogisticsGoods);
                        goodsIds.add(orderGoods.getGoodsId().longValue());
                    }
                }
            }
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("uid",uid);
            jsonObject.put("name",name);
            jsonObject.put("goodsId",exportOrderAllResponse.getGoodsId());
            jsonObject.put("orderNo",exportOrderAllResponse.getOrderNo());
            jsonObject.put("log","excel批量导入部分发货：" + exportOrderAllResponse.getGoodsName()+"，数量："+realSendAmount);
            addLogList.add(jsonObject);
        }
//        asyncSendService.partSendUpdate(goodsList,logisticsGoodsList,insertLogisticsGoodsList,partSendError);
        asyncSendService.partUpdateGoods(goodsList,partSendError);
        asyncSendService.partUpdateLogisticsGoods(logisticsGoodsList,partSendError);
        asyncSendService.partInsertLogisticsGoods(insertLogisticsGoodsList,partSendError);
        asyncSendService.noticeMaterial(noticeMaterialOut,goodsIds,name,partSendError);
        asyncSendService.batchAddLog(addLogList,partSendError);
    }

    /**
     * 插入日志记录表
     *
     * @param uid
     * @param name
     * @param orderNo
     * @param log
     */
    public boolean addLog(Long uid, String name, String orderNo, String log) {
        OrderLog orderLog = new OrderLog();
        orderLog.setOperatorId(uid);
        orderLog.setOperatorName(name);
        orderLog.setOrderSn(orderNo);
        orderLog.setLog(log);
        orderLog.setUserFlag((byte) 2);
        int rows = orderLogMapper.insert(orderLog);
        return rows > 0;
    }

    /**
     * 非自营待发货excel导入发货
     *
     * @param list
     * @param uid
     * @param name
     */
    @Transactional(rollbackFor = Exception.class)
    public void importNoSelfResponse(List<ImportNoSelfResponse> list, Long uid, String name) {
        noSelfWaitSendError.clear();
        if (list==null || list.isEmpty()) {
            return;
        }
        List<UserOrder> userOrders = new ArrayList<>();
        List<OrderGoods> orderGoods = new ArrayList<>();
        List<LogisticsGoods> logisticsGoodsList = new ArrayList<>();
        Map<String, String> expressMap = availableExpressMap();
        MessageTemplate messageTemplate = sendMessageHandler.getMessageTemplate(4);
        List<String> orderNos = new ArrayList<>();
        List<OrderLogistics> orderLogisticsList = new ArrayList<>();
        Map<Integer,List<LogisticsGoods>> logisticsGoodsMap =
                logisticsGoodsMap(list.stream().map(ImportNoSelfResponse::getOrderId).collect(Collectors.toList()));
        List<JSONObject> addLogList = new ArrayList<>();
        List<ImportNoSelfResponse> sendMessageList = new ArrayList<>();
        Map<String,String> coverImgUrlMap = new HashMap<>();
        for (ImportNoSelfResponse importNoSelfResponse : list) {
            if(!logisticsGoodsMap.containsKey(importNoSelfResponse.getOrderId())){
                continue;
            }
            if (importNoSelfResponse.getExpressCompany() == null && importNoSelfResponse.getRealLogisticsNo() == null) {
                continue;
            }
            if(importNoSelfResponse.getExpressCompany() == null || importNoSelfResponse.getRealLogisticsNo() == null){
                noSelfWaitSendError.add(importNoSelfResponse.getOrderNo()+"--运单号或快递公司为空");
                continue;
            }
            if(importNoSelfResponse.getGoodsAmount()<importNoSelfResponse.getRealSendAmount() || importNoSelfResponse.getRealSendAmount()==0){
                noSelfWaitSendError.add(importNoSelfResponse.getOrderNo()+"--实发数量大于应发数量或实发数量为0");
                continue;
            }
            if(!expressMap.containsKey(importNoSelfResponse.getExpressCompany())){
                noSelfWaitSendError.add(importNoSelfResponse.getOrderNo()+"--快递公司名称错误");
                continue;
            }
            if(!noSelfWaitSendError.isEmpty()){
                continue;
            }
            List<LogisticsGoods> logisticsGoodsList1 = logisticsGoodsMap.get(importNoSelfResponse.getOrderId()).stream()
                    .filter(l->l.getGoodsId().equals(importNoSelfResponse.getGoodsId())).collect(Collectors.toList());
            LogisticsGoods logisticsGoods;
            if(!logisticsGoodsList1.isEmpty()){
                logisticsGoods = logisticsGoodsList1.get(0);
            }else{
                continue;
            }
            logisticsGoods.setRealLogisticsNo(importNoSelfResponse.getRealLogisticsNo());
            logisticsGoods.setExpressCode(expressMap.get(importNoSelfResponse.getExpressCompany()));
            logisticsGoods.setRealSendAmount(importNoSelfResponse.getRealSendAmount());
            logisticsGoods.setRemark(importNoSelfResponse.getRemark()==null?"":importNoSelfResponse.getRemark());
            OrderLogistics orderLogistics = new OrderLogistics();
            orderLogistics.setLogisticsNo(logisticsGoods.getLogisticsNo());
            UserOrder userOrder = new UserOrder();
            userOrder.setId(importNoSelfResponse.getOrderId());
            userOrder.setConfirmTime(DateUtil.getDateAfterMinute(new Date(),
                    Integer.parseInt(timeConfiguration.getConfirmTimeMinutes())));
            userOrders.add(userOrder);
            OrderGoods orderGoodsEntity = new OrderGoods();
            orderGoodsEntity.setOrderId(importNoSelfResponse.getOrderId());
            orderGoodsEntity.setGoodsId(importNoSelfResponse.getGoodsId());
            orderGoodsEntity.setRealSendAmount(importNoSelfResponse.getRealSendAmount());
            if (importNoSelfResponse.getGoodsAmount().equals(importNoSelfResponse.getRealSendAmount())) {
                orderGoodsEntity.setGoodsStatus(LogisticsStatusEnum.WAIT_RECEIVE.getCode());
                logisticsGoods.setLogisticsStatus(LogisticsStatusEnum.WAIT_RECEIVE.getCode());
            } else {
                orderGoodsEntity.setGoodsStatus(LogisticsStatusEnum.PART_SEND.getCode());
                logisticsGoods.setLogisticsStatus(LogisticsStatusEnum.PART_SEND.getCode());
            }
            orderGoodsEntity.setRemark(importNoSelfResponse.getRemark()==null?"":importNoSelfResponse.getRemark());
            orderGoods.add(orderGoodsEntity);
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("uid",uid);
            jsonObject.put("name",name);
            jsonObject.put("goodsId",importNoSelfResponse.getGoodsId());
            jsonObject.put("orderNo",importNoSelfResponse.getOrderNo());
            jsonObject.put("log","excel批量导入非自营发货：" + importNoSelfResponse.getGoodsName()+"，数量："+importNoSelfResponse.getRealSendAmount());
            addLogList.add(jsonObject);
            coverImgUrlMap.put(logisticsGoods.getOrderNo()+logisticsGoods.getGoodsId(),logisticsGoods.getGoodsCoverImg());
            sendMessageList.add(importNoSelfResponse);
            orderNos.add(importNoSelfResponse.getOrderNo());
            logisticsGoodsList.add(logisticsGoods);
            OrderLogistics orderLogistics1 = new OrderLogistics();
            orderLogistics1.setLogisticsStatus(LogisticsStatusEnum.WAIT_RECEIVE.getCode());
            orderLogistics1.setLogisticsNo(logisticsGoods.getLogisticsNo());
            orderLogisticsList.add(orderLogistics1);
        }
//        asyncSendService.noSelfSendUpdate(userOrders,orderGoods,logisticsGoodsList,orderLogisticsList,noSelfWaitSendError);
        asyncSendService.noSelfUpdateOrderGoods(orderGoods,noSelfWaitSendError);
        asyncSendService.noSelfUpdateUserOrder(userOrders,noSelfWaitSendError);
        asyncSendService.noSelfLogisticsGoods(logisticsGoodsList,noSelfWaitSendError);
        asyncSendService.noSelfUpdateOrderLogistics(orderLogisticsList,noSelfWaitSendError);
        asyncSendService.batchAddLog(addLogList,noSelfWaitSendError);
        asyncSendService.batchNoSelfSendMessage(messageTemplate,sendMessageList,coverImgUrlMap,noSelfWaitSendError);
    }

    /**
     * 获取非自营包裹商品
     * @param orderIds
     * @return
     */
    private Map<Integer,List<LogisticsGoods>> logisticsGoodsMap(List<Integer> orderIds){
        //找出包裹商品
        QueryWrapper<LogisticsGoods> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("del_flag",0)
                .in("order_id",orderIds)
                .eq("self_flag", SelfFlagEnum.NO_SELF.getCode())
                .eq("logistics_status", LogisticsStatusEnum.WAIT_SEND.getCode());
        List<LogisticsGoods> list = logisticsGoodsMapper.selectList(queryWrapper);
        Map<Integer,List<LogisticsGoods>> map = new HashMap<>(list.size());
        for(LogisticsGoods logisticsGoods:list){
            if(map.containsKey(logisticsGoods.getOrderId())){
                map.get(logisticsGoods.getOrderId()).add(logisticsGoods);
                continue;
            }
            List<LogisticsGoods> logisticsGoodsList = new ArrayList<>();
            logisticsGoodsList.add(logisticsGoods);
            map.put(logisticsGoods.getOrderId(),logisticsGoodsList);
        }
        return map;
    }

}
